<template>
  <div>
    <div class="card table">
      <form-create
        v-model="formApi.value"
        v-model:api="formApi.fApi"
        v-bind="formApi"
        v-on="$attrs"
        @search-click="onSearch"
        @clear-click="onClear"
      ></form-create>
      <div class="table-header">
        <div class="header-button-lf">
          <slot name="left" :selection="selection"></slot>
        </div>
        <div class="header-button-ri">
          <slot name="right" :selection="selection"></slot>
        </div>
      </div>
      <el-table
        ref="table"
        v-bind="$attrs"
        :current-row-key="currentRowKey"
        :border="border"
        :data="mData"
        style="width: 100%"
        @selection-change="handleSelectionChange"
      >
        <template v-for="propItem in mColumns" :key="propItem.prop">
          <el-table-column v-if="propItem.type" :key="propItem.type" :type="propItem.type" v-bind="propItem" />
          <TableColumn v-if="!propItem.type && propItem.prop" :column="propItem">
            <template v-for="slot in Object.keys($slots)" #[slot]="scope">
              <slot :name="slot" :row="scope.row"></slot>
            </template>
          </TableColumn>
        </template>
      </el-table>
      <slot name="pagination">
        <el-pagination
          v-if="pagination"
          v-model:currentPage="params.pageNo"
          v-model:page-size="params.PageSize"
          :page-sizes="pageSizes"
          layout="->, total, sizes, prev, pager, next, jumper"
          :total="dataCount"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </slot>
    </div>
  </div>
</template>

<script setup lang='tsx'>
import { ref, reactive } from 'vue'
import TableColumn from './components/TableColumn.vue'
import { indexStore } from '@/store'
import type { TableProps } from 'element-plus'
import { usePagination } from "./hooks/usePagination"
import { formOptions } from './hooks/useFormOption'
import { formBtn } from './hooks/useFormBtn'
import { useData } from './hooks/useData'
import _ from "lodash"
import type {  paramsType, BtnType, FormType, ConfigType, Columns } from './types/index'
interface ProTableProps extends Partial<Omit<TableProps<any>, 'data'>> {
  pagination?: boolean
  pageSizes?: number[]
  pageSize?: number,
  selected?: any[]
  action?: string,
  data?: any[],
  config?: ConfigType,
  [props: string]: any,
  currentRowKey?: string | number,
  border?: boolean
}


const emit = defineEmits(['update:selected', 'update:config'])
const store = indexStore()
const props = withDefaults(defineProps<ProTableProps>(), {
  pagination: true,
  pageSizes: () => [10, 50, 100, 200, 300],
  pageSize: 10,
  selected: () => [],
  border: true,
  currentRowKey: 'id'
})

const table = ref()
const mColumns = reactive<Columns[]>(_.cloneDeep(props.config?.columns))
let formApi = reactive<ConfigType>(_.cloneDeep({
  fApi: props.config?.fApi,
  value: props.config?.value,
  rule: props.config?.rule,
  option: {...props.config?.option, ...formOptions()}
}))

watch(() => props.config, (val) => {
  if(!val) return
  const formBtn: FormType = {
    type: 'div',
    class: 'form-btns',
    children: [
      { type: 'button', field: 'search', props: { type: 'primary' }, children: ['查询'], on: { click: () => onSearch()} },
      { type: 'button', field: 'clear', props: { type: 'default' }, children: ['清空'], on: { click: () => onClear() } }
    ]
  }
  formApi?.rule?.push(formBtn)
},{
  immediate:true
})


let params = computed<paramsType>(() => {
  return {
    pageNo: 1,
    pageSize: props.pageSize,
    orderBy: 'create_time',
    orderDirection: 'DESC',
  }
})

const { selectData, getData, mData, dataCount } = useData(table, params, formApi, props )

const { handleSizeChange, handleCurrentChange } = usePagination(params, getData)
const { onSearch, onClear } = formBtn(formApi, params, getData)

const selection = ref<any>([])
const handleSelectionChange = (val: any) => {
  selection.value = val
  nextTick(() => {
    emit('update:selected', selection.value )
  })
}
defineExpose({
  selection,
  fApi: formApi.value,
  rule: formApi.rule,
  option: formApi.option,
  getData
});
</script>

<style lang='scss'>
@import './index.scss';
.form-btns {
  .el-form-item {
    margin-right: 15px !important;
  }
}
</style>